'use strict'

const http=require('http')
const fs=require('fs')

function parseBodyHeaders(data){
    let headers = {}
    let dsplit = data.split('\r\n').filter(p => p.length > 0)
    
    let ind
    let k
    for (let d of dsplit){
        ind = d.indexOf(':')

        if(ind <= 0) continue

        k = d.substring(0, ind).toLowerCase()
        
        headers[k] = d.substring(ind+1).trim()
    
    }

    let cpd = headers['content-disposition']

    //按照;分割成数组，第一个元素form-data去掉
    let clist = cpd.split(';').slice(1)

    let name, filename

    for(let a of clist){
        ind = a.indexOf('filename=')
        if(ind >= 0){
            filename = a.substring(ind+10, a.length-1)
        }
        else{
            name = a.substring(6, a.length - 1)
        }
    }

    return {
        headers,
        name,
        filename
    }

}

/**
 * 
 * @param {Buffer} bodyData 原始的Body数据
 * @param {Object} reqHeaders request.headers
 */

function parseBody(bodyData, reqHeaders){

    //content-type: mutipart/form-data; boundary=-----34294329
    let ctype = reqHeaders['content-type']
    
    //拿到分界线
    let bdy = ctype.substring(ctype.indexOf('=')+1)

    //数据中用于分割文件的分界线
    //bdy = `--$(bdy)\r\n`

    let crlf_bdy = `\r\n--${bdy}`

    //从便宜bdy的长度开始查找下一个分界线的位置
    let data_end_index = bodyData.indexOf(crlf_bdy, crlf_bdy.length)

    //body消息数据中header部分的最后索引
    let header_end_index = bodyData.indexOf('\r\n\r\n', crlf_bdy.length)

    let header_data = bodyData.toString('utf-8', crlf_bdy.length, header_end_index)

    //解析body数据中的消息头
    let hd = parseBodyHeaders(header_data)


    let fileinfo = {
        start: header_end_index + 4,
        end: data_end_index,
    }

    fileinfo.length = fileinfo.end - fileinfo.start

    return {
        name: hd.name,
        filename: hd.filename,
        headers: hd.headers,
        start: fileinfo.start,
        end: fileinfo.end,
        length: fileinfo.length
    }

}

let routerTable={
    GET:{
        '/upload':async(request,response)=>{
            let stm=fs.createReadStream('./upload.html')
            stm.pipe(response)
            stm.on('end',()=>{
                response.end()
            })
        }
    },
    POST:{
        '/upload':async(request,response)=>{
            let bufferList=[]
            let totalLength=0

            request.on('data',chunk=>{
                totalLength+=chunk.length
                bufferList.push(chunk)
            })
            let bodyData=null
            request.on('end',()=>{
                bodyData=Buffer.concat(bufferList,totalLength)
                bufferList=[]

                //解析Body数据
                let body = parseBody(bodyData, request.headers)
                console.log(body)

                response.setHeader('content-type',
                                'text/plain;charset=utf-8')
                response.end(bodyData.toString('utf-8', body.start, body.end))
            })
        }
    }
}
let serv=http.createServer()
serv.on('request',(request,response)=>{
    let rm=routerTable[request.method]
    if(!rm||!rm[request.url]){
        response.statusCode=404
        response.end('page not found')
        return
    }
    rm[request.url](request,response)
})
serv.listen(3456)